package net.sinodata.smartframework.component;

import net.sinodata.smartframework.entity.ScheduleJob;
import net.sinodata.smartframework.schedulejob.base.AbstractScheduleJob;
import net.sinodata.smartframework.schedulejob.base.ScheduleJobManager;
import net.sinodata.smartframework.schedulejob.base.ScheduleJobUtils;
import net.sinodata.smartframework.service.ScheduleJobService;
import net.sinodata.smartframework.util.ParamConfigUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;

import java.util.List;

/**
 * Description: 定时任务启动类
 * 
 * @author: yinliangyun
 * @date: 2021-5-18
 */
@Component
@Order(value = 1)
public class ScheduleJobRunner implements ApplicationRunner {
	
	private static final Logger logger = LoggerFactory.getLogger(ScheduleJobRunner.class);
	
	@Autowired
	private ScheduleJobService scheduleJobService;

	@SuppressWarnings("unchecked")
	@Override
	public void run(ApplicationArguments args) throws Exception {
		logger.info("ScheduleJobRunner init run start");
		
		// 查询数据库表schedule_job中所有数据
		List<ScheduleJob> scheduleJobList = scheduleJobService.list();
		logger.info("ScheduleJobRunner run scheduleJobList size : {}", scheduleJobList.size());

		for (ScheduleJob scheduleJob : scheduleJobList) {
			logger.info("ScheduleJobRunner run scheduleJob : {}", scheduleJob);
			
			Class<AbstractScheduleJob> scheduleJobClazz;
			// 全局开关打开 针对不同的定时任务根据启动表达式所配置的应用名称来控制具体在那个应用上是否开启该定时任务
			String localServerURL = ParamConfigUtils.getLocalServerURL();
			String serverPattern = ScheduleJobUtils.toJavaPattern(scheduleJob.getFlagExpress().trim());
			logger.info("ScheduleJobRunner run localServerURL : {}, serverPattern : {}", localServerURL, serverPattern);
			if (localServerURL.matches(serverPattern)) {
				try {
					scheduleJobClazz = (Class<AbstractScheduleJob>) Class.forName(scheduleJob.getJobClass());
					ScheduleJobManager.getInstance().startJob(scheduleJobClazz,
							scheduleJob.getJobName(),
							scheduleJob.getCronExpression(),
							scheduleJob.getMultiRunFlag());
				} catch (Exception e) {
					logger.error("ScheduleJobRunner run exception JobName : {}", scheduleJob.getJobName() + "_" + e.getMessage(), e);
					throw e;
				}
			}
		}

		ScheduleJobManager.getInstance().start();
		logger.info("ScheduleJobRunner run scheduleJob end");
	}

}
